package com.hitqz.robot;

import com.google.common.collect.Lists;
import com.hitqz.robot.api.business.enums.BrandEnum;
import com.hitqz.robot.camera.IEquipmentService;
import com.hitqz.robot.camera.configure.EquipmentCmdEnum;
import com.hitqz.robot.camera.dto.*;
import com.hitqz.robot.util.PlcToolKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author xupkun
 * @date 2024/10/4
 */
@Slf4j
@Service("PlcModuleService")
public class PlcModuleService implements IEquipmentService {


    /**
     * map-- ip
     *
     * 对应 FormFieldConfig字段
     */
    private static Map<String, Map<String, Object>> readDataKey;

    @Override
    public BrandEnum brand() {
        return BrandEnum.CAR_PLC;
    }

    @Override
    public boolean intSdk() {
        return true;
    }

    @Override
    public boolean login(EquipmentLoginParamsDto dto) {
        PlcToolKit.login(dto.getIp(), dto.getPort());
        return true;
    }

    @Override
    public boolean loginout(String ip) {
        return IEquipmentService.super.loginout(ip);
    }

    @Override
    public IEquipmentCmdResult executeCmd(QueryParamsDto dto, boolean ansyc, EquipmentCmdEnum cmdEnum, IEquipmentCmdParamsDto cmdParamsDto) {
        switch (cmdEnum) {
            case RESET -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 10, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 1, 1);
            }
            case STOP -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 1);
            }
            case UN_STOP -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
            }
            case START_MATCH -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 11, 0);
                //
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 10, 1);
                if (ansyc) {
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    }catch (Exception e) {
                    }
                    while (true) {
                        int match = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 11);
                        if (match == 1) {
                            log.info("模组对接完成");
                            break;
                        }
                    }
                }

            }
            case FET_OIL -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 13, 0);
                FetchOilDto fetchOilDto = (FetchOilDto) cmdParamsDto;
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 12, fetchOilDto.getSn());
            }
            case MATCH_EXIT -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 16, 1);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 10, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 17, 0);
                while (true) {
                    int match = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 17);
                    if (match == 1) {
                        log.info("plc模组退出完成");
                        break;
                    }
                }
            }
            case ENABLE_SIDES -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 9, 1);
                SidesWayDto sidesWayDto = (SidesWayDto) cmdParamsDto;
                int distance = sidesWayDto.getDistance();
                log.info("设置移动距离：" + distance);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 8, distance);
                if (ansyc) {
                    while (true) {
                        try {
                            TimeUnit.SECONDS.sleep(1);
                        }catch (Exception e) {

                        }
                        int enable = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 9);
                        int moveDistance = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 8);
                        if ((enable == 0 || enable == 65535) ) {
                            log.info("移动使能完成:" + enable);
                            break;
                        }
                    }
                }
            }
            case ENABLE_SIDES_WAY -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 9, 1);
            }
            case ERROR_RESET -> {
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 3, 0);
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 5, 1);
            }
            case WRITE_SPEED -> {
                WriteSpeedParamsDto writeSpeedParamsDto = (WriteSpeedParamsDto) cmdParamsDto;
                log.info("Writing speed：" + writeSpeedParamsDto.getSpeed());
                PlcToolKit.writeRegister(dto.getIp(), dto.getPort(), 1004, writeSpeedParamsDto.getSpeed()
                );
            }
        }
        return null;
    }

    @Override
    public List<EquipmentParamsDto> getEquipmentParams(QueryParamsDto dto) {
        List<EquipmentParamsDto> paramsDtos = Lists.newArrayList();
        // 复位状态
        int resetStatus = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 2);
        paramsDtos.add(new EquipmentParamsDto("复位状态", "reset", String.valueOf(resetStatus), resetStatus == 1 ? "复位完成" : "未完成"));
        int stopStatus = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 3);
        paramsDtos.add(new EquipmentParamsDto("急停", "stopStatus", String.valueOf(stopStatus), stopStatus == 1 ? "触发" : "未触发"));
        int error = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 3);
        paramsDtos.add(new EquipmentParamsDto("故障码", "error", String.valueOf(error), ""));
        int leftDistance =  PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 6);
        int rightDistance =  PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 7);
        paramsDtos.add(new EquipmentParamsDto("左测距传感器", "leftDistance", String.valueOf(leftDistance), ""));
        paramsDtos.add(new EquipmentParamsDto("右测距传感器", "rightDistance", String.valueOf(rightDistance), ""));
        int leftDistanceMove =  PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 20);
        int rightDistanceMove =  PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 21);
        paramsDtos.add(new EquipmentParamsDto("左测距传感器(浮动)", "leftDistanceMove", String.valueOf(leftDistanceMove), ""));
        paramsDtos.add(new EquipmentParamsDto("右测距传感器(浮动)", "rightDistanceMove", String.valueOf(rightDistanceMove), ""));
        int match =   PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 11);
        paramsDtos.add(new EquipmentParamsDto("模组对接信号", "match", String.valueOf(match), match == 1 ? "对接完成" : "未完成"));
        //对接退出完成
        int fetchStatus =  PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 13);
        int flow1 = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 14);
        int flow2 = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 15);
        paramsDtos.add(new EquipmentParamsDto("流量计1", "flow1", String.valueOf(flow1), ""));
        paramsDtos.add(new EquipmentParamsDto("流量计2", "flow2", String.valueOf(flow2), ""));
        paramsDtos.add(new EquipmentParamsDto("取油状态", "fetStatus", String.valueOf(fetchStatus), fetchStatus == 1 ? "完成":"未完成"));
        //对接退出完成
        int matchExit = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 17);
        paramsDtos.add(new EquipmentParamsDto("对接完成退出", "matchExit", String.valueOf(matchExit), matchExit== 1 ? "完成":"未完成"));
        int enable = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 9);
        paramsDtos.add(new EquipmentParamsDto("横移模组使能", "enable", String.valueOf(enable), enable== 1 ? "使能":"未使能"));
        int left = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 18);
        int right = PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 19);
        paramsDtos.add(new EquipmentParamsDto("左到位信号", "left", String.valueOf(left), ""));
        paramsDtos.add(new EquipmentParamsDto("右到位信号", "right", String.valueOf(right), ""));
        int oil =  PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 22);
        paramsDtos.add(new EquipmentParamsDto("取费油时间", "oil", String.valueOf(oil), ""));
        paramsDtos.add(new EquipmentParamsDto("取油速度", "fetOilSpeed", String.valueOf(PlcToolKit.readSingleRegister(dto.getIp(), dto.getPort(), 1004)), ""));
        return paramsDtos;
    }

    @Override
    public List<EquipmentParamsDto> getDeviceParamsData(QueryParamsDto dto, EquipmentCmdEnum cmdEnum) {




        return Lists.newArrayList();
    }

    @Override
    public IEquipmentCmdResult getExecuteCmdResult(EquipmentCmdEnum cmdEnum) {
        return IEquipmentService.super.getExecuteCmdResult(cmdEnum);
    }

    @Override
    public boolean setEquipmentParams(QueryParamsDto dto, List<EquipmentParamsDto> paramsDtos, boolean async) {




        return true;
    }

}
